<?php
/**
 * Project:     drylamp - rapid application development framework for php
 * File:        ScaffoldNode.php
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *
 * @copyright 2008 Ilya St.
 * @author Ilya St. <provided at gmail dot com>
 * @version 1.0
 */


// TODO: 
// 1. Why ScaffoldNode is not all static?
// 2. Why ScaffoldNode is a separate class?
// 3. Does the name "ScaffoldNode" make any sense for his class?


class ScaffoldNode {
  protected static $mEmitIndex;
  public static $mTplEngineObj;

  
  /**
   * Array of Scaffoldable objects of a SAME TYPE, or just a single Scaffoldable object
   * @var mixed
   */
  protected $mData;
  
  public function __construct($pData) {
    $this->mData = $pData;
    self::$mEmitIndex++;
  }
  
  public function resetData($pData) {
    if (!isset($this->mData)) throw new ScaffoldNodeException("Can't reset - Data hasn't been set for this ScaffoldNode");
    $this->mData = $pData; 
  }
  
  public function emit($pSaveAsPath = NULL) {
    $emitIndex = self::$mEmitIndex; // preserve emitIndex
    
    $sampleObj = NULL;
    if (is_array($this->mData)) {
      if (count($this->mData)==0) return NULL;
      $t1 = $this->getIterator($this->mData);
      $sampleObj = $this->mData[0];
    }
      else {
        $sampleObj = $this->mData;
        $t1 = $sampleObj->getSingleEmitTpl();
      }
    $containerTpl = $sampleObj->getContainerTpl(); 
    $containerTpl = str_replace(Scaffolder::CONTAINER_CONTENT, $t1, $containerTpl );
    $containerTpl = str_replace(Scaffolder::INDEX_TOKEN, $emitIndex, $containerTpl);
    if ( !is_null($pSaveAsPath) ) {
      file_put_contents($pSaveAsPath, $containerTpl);
    }
    return $containerTpl;      
  }
  
  
  protected function getIterator(Array $pData) {
    $iter = file_get_contents(dirname(__FILE__).'/tpl_iterator.html');
    $iter = str_replace(Scaffolder::SINGLE_EMIT_TOKEN, $pData[0]->getSingleEmitTpl(), $iter);
    return $iter;
  }
  
  
  public function assignTplVars() {
    if (is_array($this->mData)) {
      self::$mTplEngineObj->assign("var_". self::$mEmitIndex, $this->mData);
      foreach( $this->mData as $d ) {
        if ($d instanceof ScaffoldableParent) {
          $d_children = $d->getChildren();
          foreach( $d_children as $dc ) $dc->assignTplVars();
        }
      }
    }
     else {
       self::$mTplEngineObj->assign("dataObject_". self::$mEmitIndex, $this->mData);
     }
  }
  
  public function emitEval() {
    $tmpName = "/tmp/drylamp_tmp_tpl_".getmygid()."_".time().".tpl";
    $this->emit($tmpName);
    $this->assignTplVars();
    $tplReturn = self::$mTplEngineObj->fetch($tmpName);
    unlink($tmpName);
    return $tplReturn;
  }
  
}

class ScaffoldNodeException extends Exception {};
